// 普通管理员
require("../models/relation")
require("./publicFn/asyncExits")
const publicFn = require("./publicFn/init")
// 公用的导入
const init = require("../util/init")

/**
 * 管理员登录
 * @param {*} adminObj 管理员账号对象
 * @param {*} adminObj.adminId 学工号
 * @param {*} adminObj.loginPwd 密码
 */
exports.login = async function (adminObj) {
    adminObj = init.pick(adminObj, "adminId", "loginPwd")
    const ralu = {
        adminId: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },

        loginPwd: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        }
    }
    try {
        const Exits = init.validate(adminObj, ralu)
        if (Exits) {
            throw Exits
        }
    } catch (err) {
        return {
            code: 401,
            err
        }
    }
    const res = await init.AdminInfon.findOne({
        attributes: ["id", "adminId", "authentication"],
        where: {
            adminId: adminObj.adminId,
            loginPwd: init.md5(adminObj.loginPwd)
        }
    })
    if (res) {
        return {
            state: 1,
            token: res.toJSON()
        }
    }
    return {
        state: 2,
        token: null
    }

}

/**
 * 管理员个人信息
 * @param {*} id 用户id 
 */
const Info = async function (id) {
    const ralu = {
        id: {
            presence: {
                allowEmpty: false
            },
            type: "number",
            AdminExits: true
        }
    }
    try {
        await init.validate.async({
            id
        }, ralu)
    } catch (err) {
        return {
            code: 401,
            err
        }
    }

    const res = await init.AdminInfon.findByPk(id, {
        attributes: ["id", "adminId", "Nickname", "phone", "avatar", "authentication"]
    })
    if (res) {
        let where = {};
        if (res.toJSON().authentication) {
            where.AdminInfonId = res.toJSON().id;
        }
        const ManagementDormitory = await init.Dormitory.findAll({
            where,
            attributes: ["id", "DormitoryName", "floorNum", "roomNum", "dormitoryresided"]
        })
        const dormitoryData = JSON.parse(JSON.stringify(ManagementDormitory))
        return {
            ...res.toJSON(),
            manageArr: [
                ...dormitoryData
            ]
        }
    }



}

exports.Info = Info


/**
 * 发布评论
 * @param {Object} evaluateObj 评论对象
 * @param {Number} evaluateObj.fraction 评分
 * @param {String} evaluateObj.comment 评语
 * @param {Number} evaluateObj.roomNoId 宿舍id
 * @param {Number} evaluateObj.id 管理员id
 */
exports.evaluate = async function (evaluateObj) {
    evaluateObj = init.pick(evaluateObj, "fraction", "comment", "roomNoId", "id")
    init.validate.validators.RoomNoIdExits = async function (value) {
        const res = await init.RoomNo.findOne({
            where: {
                id: value,
                roomResided: {
                    [init.Op.not]: 0
                }
            }
        })
        if (res) {
            return
        }
        return "is not exits or Not checked in"
    }
    const ralu = {
        fraction: {
            presence: {
                allowEmpty: false
            },
            type: "number",
            numericality: {
                onlyInteger: true,
                greaterThan: 0,
                lessThanOrEqualTo: 100
            },

        },
        comment: {
            presence: {
                allowEmpty: false
            },
            type: "string"
        },
        roomNoId: {
            presence: {
                allowEmpty: false
            },
            type: "number",
            RoomNoIdExits: true
        },
        id: {
            presence: {
                allowEmpty: false
            },
            type: "number",
            AdminExits: true
        }
    }
    try {
        await init.validate.async(evaluateObj, ralu)
    } catch (err) {
        return {
            code: 401,
            err
        }
    }

    const res = await init.Comment.create({
        fraction: evaluateObj.fraction,
        comment: evaluateObj.comment,
        time: +init.moment.utc(),
        RoomNoId: evaluateObj.roomNoId,
        AdminInfonId: evaluateObj.id
    })
    const Json = res.toJSON()
    const reslut = {
        fraction: Json.fraction,
        comment: Json.comment,
        time: Json.time,
        AdminInfonId: Json.AdminInfonId,
        text: "评论成功"
    }
    return reslut


}





/**
 * 获取学生信息
 * @param {Number} page 页码
 * @param {Number} limit 多少条数据
 * @param {Object} keyword 查询的对象 {dormitoryId: "宿舍楼id",floorNumber : "楼层id",roomNo: "宿舍id",loginId: "学号",nickname: "学生姓名"}
 */
exports.students = async function (page = 1, limit = 10, id, keyword = {}) {
    const ralu = {
        page: {
            presence: {
                allowEmpty: false
            },
            type: "number",
        },
        limit: {
            presence: {
                allowEmpty: false
            },
            type: "number",
        },
        id: {
            presence: {
                allowEmpty: false
            },
            type: "number",
        },
        keyword: {
            type: "object",
        }
    }
    const keywordExits = {
        dormitoryId: {
            type: "number"
        },
        floorId: {
            type: "number"
        },
        roomNoId: {
            type: "number"
        },
        loginId: {
            type: "string"
        },
        nickname: {
            type: "string"
        }
    }
    try {
        const Exits = init.validate({
            page,
            limit,
            id,
            keyword
        }, ralu)
        const WExits = init.validate(keyword, keywordExits)
        if (Exits) {
            throw Exits
        }
        if (WExits) {
            throw WExits
        }
    } catch (err) {
        return {
            code: 401,
            err
        }
    }

    const adminDormitory = []
    if (!keyword.dormitoryId) {
        const getAdminInfo = await Info(id)
        getAdminInfo.manageArr.forEach(item => {
            adminDormitory.push(item.id)
        })
    }
    const res = await init.StudentSInfon.findAndCountAll({
        distinct: true,
        offset: (page - 1) * limit,
        limit: limit,
        order: [
            ['id', 'ASC']
        ],
        attributes: ["id", "studentId", "Nickname", "phone", "avatar", "checkInTime"],
        where: {
            [init.Op.and]: [{
                    studentId: keyword.loginId ? keyword.loginId : {
                        [init.Op.not]: null
                    }
                },
                {
                    Nickname: keyword.nickname ? {
                        [init.Op.like]: `%${keyword.nickname}%`
                    } : {
                        [init.Op.not]: null
                    }
                }
            ]
        },
        include: [{
                model: init.Getup,
                attributes: ["time", "isGetup"],

            },
            {
                model: init.Destination,
                attributes: ["time", "isDestination"],

            },
            {
                model: init.Clean,
                attributes: ["time"],

            },
            {
                model: init.Bednumber,
                attributes: ["id", "bednumberId"],
                required: true,
                include: [{
                    model: init.RoomNo,
                    attributes: ["id", "roomNo"],
                    required: true,
                    where: {
                        id: keyword.roomNoId ? keyword.roomNoId : {
                            [init.Op.not]: null
                        }
                    },
                    include: [{
                        model: init.Floor,
                        attributes: ["id", "floorNumber"],
                        required: true,
                        where: {
                            id: keyword.floorId ? keyword.floorId : {
                                [init.Op.not]: null
                            }
                        },
                        include: [{
                            model: init.Dormitory,
                            attributes: ["id", "DormitoryName"],
                            required: true,
                            where: {
                                id: keyword.dormitoryId ? keyword.dormitoryId : {
                                    [init.Op.in]: adminDormitory
                                }
                            }
                        }]
                    }]
                }]
            }
        ],
    })
    let reslut = {}
    reslut.total = JSON.parse(JSON.stringify(res)).count
    reslut.rows = JSON.parse(JSON.stringify(res)).rows.map(itme => {
        return {
            id: itme.id,
            studentID: itme.studentId,
            studentName: itme.Nickname,
            phone: itme.phone,
            checkInTime: itme.checkInTime,
            dormitoryId: itme.Bednumber.RoomNo.Floor.Dormitory.id,
            dormitoryName: itme.Bednumber.RoomNo.Floor.Dormitory.DormitoryName,
            floorID: itme.Bednumber.RoomNo.Floor.id,
            floorNumber: itme.Bednumber.RoomNo.Floor.floorNumber,
            roomNoId: itme.Bednumber.RoomNo.id,
            roomNo: itme.Bednumber.RoomNo.roomNo,
            bednumberId: itme.Bednumber.id,
            bednumber: itme.Bednumber.bednumberId,
            getUpProbability: publicFn.percentage(itme.checkInTime, itme.Getups, "isGetup"),
            returnProbability: publicFn.percentage(itme.checkInTime, itme.Destinations, "isDestination"),
            cleanProbability: publicFn.percentage(itme.checkInTime, itme.Cleans),
            latestGetup: itme.Getups.reduce((a, b) => {
                return a.time < b.time ? b : a;
            })
        }
    })
    return reslut


}

/**
 * 获取起床记录
 * @param {Number} page 页码,
 * @param {Number} limit 页容量
 * @param {Object} conditionObj 条件对象
 * @param {Number} conditionObj.studentId 学生id 必填
 * @param {string} conditionObj.startingTime 起始时间
 * @param {string} conditionObj.endTime 终止时间
 */
exports.getup = async function (page = 1, limit = 10, conditionObj) {


    const resluts = await publicFn.RecordViewing({
        page,
        limit,
        conditionObj
    }, async function (where) {

        const res = await init.Getup.findAndCountAll({
            order: [
                ["time", "DESC"]
            ],
            offset: (page - 1) * limit,
            limit,
            where,
            include: [{
                model: init.StudentSInfon,
                attributes: ["id", "Nickname", "studentId"]

            }]
        })
        let reslut = {}
        reslut.total = JSON.parse(JSON.stringify(res)).count
        reslut.rows = JSON.parse(JSON.stringify(res)).rows.map(itme => {
            let total = {
                id: itme.StudentSInfon.id,
                studentName: itme.StudentSInfon.Nickname,
                studentID: itme.StudentSInfon.studentId,
                time: itme.time,
                isGetUp: itme.isGetup
            }
            return total
        });
        return reslut
    })
    return resluts


}



/**
 * 获取归宿记录
 * @param {Number} page 页码,
 * @param {Number} limit 页容量
 * @param {Object} conditionObj 条件对象
 * @param {Number} conditionObj.studentId 学生id 必填
 * @param {string} conditionObj.startingTime 起始时间
 * @param {string} conditionObj.endTime 终止时间
 */
exports.destination = async function (page = 1, limit = 10, conditionObj) {
    const resluts = await publicFn.RecordViewing({
        page,
        limit,
        conditionObj
    }, async function (where) {
        const res = await init.Destination.findAndCountAll({
            offset: (page - 1) * limit,
            limit,
            order: [
                ["time", "DESC"]
            ],
            where,
            include: [{
                model: init.StudentSInfon,
                attributes: ["id", "Nickname", "studentId"]
            }]
        })
        let reslut = {}
        reslut.total = JSON.parse(JSON.stringify(res)).count
        reslut.rows = JSON.parse(JSON.stringify(res)).rows.map(itme => {
            let total = {
                id: itme.StudentSInfon.id,
                studentName: itme.StudentSInfon.Nickname,
                studentID: itme.StudentSInfon.studentId,
                time: itme.time,
                isDestination: itme.isDestination
            }
            return total
        });
        return reslut
    })
    return resluts
}

/**
 * 获取打扫记录
 * @param {Number} page 页码,
 * @param {Number} limit 页容量
 * @param {Object} conditionObj 条件对象
 * @param {Number} conditionObj.studentId 学生id 必填
 * @param {string} conditionObj.startingTime 起始时间
 * @param {string} conditionObj.endTime 终止时间
 */
exports.clean = async function (page = 1, limit = 10, conditionObj) {
    try {
        const resluts = publicFn.RecordViewing({
            page,
            limit,
            conditionObj
        }, async function (where) {
            const res = await init.Clean.findAndCountAll({
                offset: (page - 1) * limit,
                order: [
                    ["time", "DESC"]
                ],
                limit,
                where,
                include: [{
                    model: init.StudentSInfon,
                    attributes: ["id", "Nickname", "studentId"]
                }]
            })

            let reslut = {}
            reslut.total = JSON.parse(JSON.stringify(res)).count
            reslut.rows = JSON.parse(JSON.stringify(res)).rows.map(itme => {
                let total = {
                    id: itme.StudentSInfon.id,
                    studentName: itme.StudentSInfon.Nickname,
                    studentID: itme.StudentSInfon.studentId,
                    time: itme.time,
                }
                return total
            });
            return reslut
        })
        return resluts
    } catch (err) {
        return {
            code: 401,
            err
        }
    }
}



/**
 * 修改密码
 * @param {Object} admin 用户提交数据
 * @param {number} admin.id 用户id
 * @param {string} admin.newPwd 新密码
 * @param {string} admin.confirmPwd 确认密码
 * @param {string} admin.oldPwd 旧密码
 */
exports.updataLoginPwd = async function (admin) {
    admin = init.pick(admin, "id", "newPwd", "confirmPwd", "oldPwd")
    const rule = {
        id: {
            presence: {
                allowEmpty: false
            },
            type: "number",
        },
        newPwd: {
            presence: {
                allowEmpty: false
            },
            type: "string",
            length: {
                minimum: 6,
                maximum: 10,
            },
            equality: "confirmPwd"
        },
        confirmPwd: {
            presence: {
                allowEmpty: false
            },
            type: "string",
            length: {
                minimum: 6,
                maximum: 10,
            },
        },
        oldPwd: {
            presence: {
                allowEmpty: false
            },
            type: "string",
            length: {
                minimum: 6,
                maximum: 10,
            },
        }
    }

    try {
        const Exits = init.validate(admin, rule);
        if (Exits) {
            throw Exits
        }
        if (admin.oldPwd === admin.newPwd) {
            throw "The new and old passwords cannot be the same"
        }
    } catch (err) {
        return {
            code: 401,
            err
        }
    }

    const isRes = await init.AdminInfon.findOne({
        where: {
            id: admin.id,
            loginPwd: init.md5(admin.oldPwd)
        }
    })
    if (!isRes) {
        return {
            state: 2,
            text: "旧密码有问题"
        }
    }
    const res = await init.AdminInfon.update({
        loginPwd: init.md5(admin.newPwd)
    }, {
        where: {
            id: admin.id
        }
    })
    if (res[0]) {
        return {
            state: 1,
            text: "修改成功"
        }
    } else {
        throw "Modification failed"
    }



}

/**
 * 修改头像
 * @param {number} id 用户id
 * @param {string} avatar 学生头像
 * 
 */
exports.updateAvatar = async function ({
    id,
    avatar
}) {
    const rule = {
        id: {
            presence: {
                allowEmpty: false
            },
            type: "number",
        },
        avatar: {
            presence: {
                allowEmpty: false
            },
            type: "string",
        }
    }
    try {
        const Exits = init.validate({
            id,
            avatar
        }, rule);
        if (Exits) {
            throw Exits
        }
    } catch (err) {
        return {
            code: 401,
            err
        }
    }
    const res = await init.AdminInfon.update({
        avatar
    }, {
        where: {
            id
        }
    })
    if (res[0] === 1) {
        return "修改成功"
    }


}
/**
 * 维修完成
 * @param {number} Repair.id 报修id
 * @param {string} Repair.RepairEndImg 维修完成图片
 * @param {string} Repair.ResponsiblePerson 负责人
 */
exports.putService = async function(Repair){
    Repair = init.pick(Repair,"id","RepairEndImg","ResponsiblePerson")
    // 验证维修id是否存在
    init.validate.validators.RepairIdExits = async function(value){
        const res = await init.RepairReport.findByPk(value)
        if(res){
            return
        }
        return "is not Exits"
    }
    const ralu = {
        id:{
            presence: {
                allowEmpty: false
            },
            type: "number",
            RepairIdExits: true,
        },
        RepairEndImg:{
            presence: {
                allowEmpty: false
            },
            type: "string",
        },
        ResponsiblePerson:{
            presence: {
                allowEmpty: false
            },
            type: "string",
        }
    }

    try{
        await init.validate.async(Repair,ralu)
    }catch(err){
        return{
        
            code: 401,
            err
        }
    }
    const res = await init.RepairReport.update({RepairEndTime: +init.moment.utc(),RepairEndImg:Repair.RepairEndImg,ResponsiblePerson:Repair.ResponsiblePerson},{
        where:{
            id:Repair.id,
        }
    })
    if(res[0]){
        return "维修成功"
    }
}
